package main;

import ai.MiniMax;
import ai.Node;
import checkers.*;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

public class Main implements Observer {

    private CheckersProblem checkersProblem;
    private CheckersGUI checkersGUI;

    public Main() {
        checkersProblem = new CheckersProblem();
        checkersGUI = new CheckersConsoleGUI();
        checkersGUI.addObserver(this);
        checkersGUI.showBoard(checkersProblem.getCurrentState());
        //printMovements(checkersProblem);
        checkersGUI.requestUserMovement(checkersProblem.avaiableMovements());
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new Main();
    }

    @Override
    public void update(Observable o, Object arg) {
        if (o == checkersGUI) {
            if (arg == CheckersGUI.NOTIFY_USER_HAS_CHOOSED_MOVEMENT) {
                CheckersMovement lastUserChosenMovement = checkersGUI.getLastUserChosenMovement();
                checkersProblem.getCurrentState().applyMovement(lastUserChosenMovement);
                checkersGUI.showBoard(checkersProblem.getCurrentState());

                iaPlays();

                checkersGUI.requestUserMovement(checkersProblem.avaiableMovements());
            }
        }
    }

    private void printMovements(CheckersProblem checkersProblem) {
        for (CheckersMovement m : checkersProblem.avaiableMovements()) {
            for (CheckersOperation o : m.getMovementsList()) {
                System.out.print((char) ('A' + o.x));
                System.out.print((o.y + 1) + " ");
                switch (o.operation) {
                    case CheckersOperation.BECOME_KING:
                        System.out.print("BECOME_KING");
                        break;
                    case CheckersOperation.REMOVE_PIECE:
                        System.out.print("REMOVE_PIECE");
                        break;
                    case CheckersOperation.SOURCE_POSITION:
                        System.out.print("SOURCE_POSITION");
                        break;
                    case CheckersOperation.TARGET_POSITION:
                        System.out.print("TARGET_POSITION");
                        break;
                }
                System.out.println();
            }
            System.out.println();
        }
    }

    private void iaPlays() {

        List<CheckersMovement> avaiableMovements = checkersProblem.avaiableMovements();
        MiniMax miniMax = new MiniMax(checkersProblem, checkersProblem.getCurrentState().getCurrentPlayer());        

        CheckersMovement bestMovement = null;
        float bestUtilityValue = Float.NEGATIVE_INFINITY;

        for (CheckersMovement moviment : avaiableMovements) {
            CheckersState state = checkersProblem.getCurrentState().clone();
            state.applyMovement(moviment);
            Node node = new Node(1, state);
            node.setUtilityValue(miniMax.minValue(node, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY));
            if (bestMovement == null || bestUtilityValue < node.getUtilityValue()) {
                bestMovement = moviment;
                bestUtilityValue = node.getUtilityValue();
            }            
        }
        
        checkersProblem.getCurrentState().applyMovement(bestMovement);
        checkersGUI.showBoard(checkersProblem.getCurrentState());
        
    }
}
